<?php
/* *
 * 功能：报关接口接入页
 * 版本：3.3
 * 修改日期：2012-07-23
 * 说明：
 * 以下代码只是为了方便商户测试而提供的样例代码，商户可以根据自己网站的需要，按照技术文档编写,并非一定要使用该代码。
 * 该代码仅供学习和研究支付宝接口使用，只是提供一个参考。

 *************************注意*************************
 * 如果您在接口集成过程中遇到问题，可以按照下面的途径来解决
 * 1、商户服务中心（https://b.alipay.com/support/helperApply.htm?action=consultationApply），提交申请集成协助，我们会有专业的技术工程师主动联系您协助解决
 * 2、商户帮助中心（http://help.alipay.com/support/232511-16307/0-16307.htm?sh=Y&info_type=9）
 * 3、支付宝论坛（http://club.alipay.com/read-htm-tid-8681712.html）
 * 如果不想使用扩展功能请把扩展功能参数赋空值。
 */
namespace addons\heycustoms\library\Heycustom;

require_once("lib/heycustom_core.function.php");
require_once("lib/generate_xml.php");

/**
 * 
 */
class Heycustom {
	
	protected $order_config;
	protected $gateway_url;

    public $errmsg = '';

    protected $guid;
    protected $data = array(
        'Order' => array(
            'OrderHead'=>array(),
            'OrderList'=>array()
        ),
        'BaseTransfer'=>array()
    );

	public function __construct($gateway_url) {
	    // $this->order_config = $order_config;
        // $this->setBaseTransfer($order_config);
	    $this->gateway_url = $gateway_url;
	}

    public function setBaseTransfer($baseTransfer){
        if ($flag = $this->verifyBaseTransfer($baseTransfer)) {
            $this->data['BaseTransfer'] = $baseTransfer;
        }
        return $flag;
    }

    public function setOrderHead($orderHeader){
        if ($flag = $this->verifyOrderHead($orderHeader)) {
            $this->guid = $orderHeader['guid'];
            $this->data['Order']['OrderHead'] = $orderHeader;
        }
        return $flag;
    }

    public function setOrderList($orderList){
        if (empty($orderList)) {
            $this->errmsg = '订单无商品数据';
            return false;
        }
        foreach ($orderList as $_key => $_row) {
            $flag = $this->verifyGoodsInfo($_row);
            if (!$flag) {
                $this->errmsg = '商品：'.$_row['itemName'].' '.$this->errmsg;
                return false;
            }
            $_row['gnum'] = $_row['gnum']?$_row['gnum']:count($this->data['Order']['OrderList']) + 1;
            $this->data['Order']['OrderList'][] = $_row;

        }
        return true;
    }

    public function setData($baseTransfer = array(), $orderHead = array(), $orderList = array()) {
        if (!empty($baseTransfer)) {
            if(!($flag = $this->setBaseTransfer($baseTransfer))) return false;
        }
        if (!empty($orderHead)) {
            if(!($flag = $this->setOrderHead($orderHead))) return false;
        }
        if (!empty($orderList)) {
            if(!($flag = $this->setOrderList($orderList))) return false;
        }

        $xml_data = generate_xml($this->data);
        if (!$xml_data) {
            $this->errmsg = 'xml数据格式生成失败';
            return false;
        }
        return $xml_data;
    }

    /**
     * 自定义captcha验证事件
     */
    public function query($xmlData = array()) {
        if (empty($xmlData)) {
            $xmlData = $this->setData();
        }

        return $this->_request($xmlData);
    }

    private function _request($xmlData){
        //建立请求
        $return_xml = $this->getXmlPOST($this->gateway_url, $xmlData);
        /*debug 
        */
        //解析XML
        if ($return_xml) {
            try {
                $xml_arr = @simplexml_load_string($return_xml);
                $xml_arr = @json_encode($xml_arr);
                $xml_arr = @json_decode($xml_arr,true);
                //解析XML
                if( !empty($xml_arr)) {
                    return $xml_arr;
                }else{
                    $this->errmsg = '请求出现未知错误';
                    return false;
                }
            } catch (Exception $e) {
                $this->errmsg = $e->getMessage();
                return false;
            }
        }
        return false;
    }

    public function getXmlPOST($api_url, $xmlData) {
        // $api_url = 'http://wang.net/xml/getXml.php'; //接收xml数据的文件
        $header[] = "Content-type: text/xml;charset=utf-8";      //定义content-type为xml,注意是数组
        $ch = curl_init ($api_url);
        curl_setopt($ch, CURLOPT_URL, $api_url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER,true);
        curl_setopt($ch, CURLOPT_HTTPHEADER,$header);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch,CURLOPT_POSTFIELDS, $xmlData);
        $response = curl_exec($ch);
        if(curl_errno($ch)){
            $this->errmsg = curl_error($ch);
        }
        curl_close($ch);

        if ($response) {
            return $response;
        }else{
            $this->errmsg = '请求无返回信息';
            return false;
        }
    }

    /**
     * 验证参数
     */
    public function verifyBaseTransfer($param) {

        // 传输企业代码
        if (!isset($param['copCode']) || !$param['copCode']) {$this->errmsg = '缺少参数copCode';return false;}
        // 传输企业名称
        if (!isset($param['copName']) || !$param['copName']) {$this->errmsg = '缺少参数copName';return false;}
        // 报文传输模式
        if (!isset($param['dxpMode']) || !$param['dxpMode']) {$this->errmsg = '缺少参数dxpMode';return false;}
        // 报文传输编号
        if (!isset($param['dxpId']) || !$param['dxpId']) {$this->errmsg = '缺少参数dxpId';return false;}
        // 备注
        // if (!isset($param['note']) || $param['note']) {$this->errmsg = '缺少参数note';return false;}             // 非必填

        return true;
    }

	/**
     * 验证参数
     */
    public function verifyOrderHead($param) {

        // 企业系统生成36位唯一序号（英文字母大写）。
        if (!isset($param['guid']) || !$param['guid']) {$this->errmsg = '缺少参数guid';return false;}
        if (strlen($param['guid']) != 36) {$this->errmsg = '参数guid需有36位';return false;}
        // 企业报送类型。1-新增 2-变更 3-删除。默认为1。
        if (!isset($param['appType']) || !$param['appType']) {$param['appType'] = '1';}
        if (!in_array($param['appType'], array('1','2','3'))) {$this->errmsg = '报送类型格式应为:1(新增)或2(变更)或3(删除)';return false;}
        // 企业报送时间。格式:YYYYMMDDhhmmss。
        if (!isset($param['appTime']) || !$param['appTime']) {$param['appTime'] = date('Ymdhis',time());}
        if (strlen($param['appTime']) != 14) {$this->errmsg = '报送时间格式应为:YYYYMMDDhhmmss';return false;}
        // 业务状态:1-暂存,2-申报,默认为2。
        if (!isset($param['appStatus']) || !$param['appStatus']) {$param['appStatus'] = '2';}
        if (!in_array($param['appStatus'], array('1','2'))) {$this->errmsg = '业务状态格式应为:1(暂存)或2(申报)';return false;}
        // 电子订单类型：I进口
        if (!isset($param['orderType']) || !$param['orderType']) {$param['orderType'] = 'I';}
        if (!in_array($param['orderType'], array('I'))) {$this->errmsg = '订单类型应为:I(进口)';return false;}
        // 交易平台的订单编号，同一交易平台的订单编号应唯一。订单编号长度不能超过60位。
        if (!isset($param['orderNo']) || !$param['orderNo']) {$this->errmsg = '缺少订单编号';return false;}
        if (strlen($param['orderNo']) > 60) {$this->errmsg = '订单编号数据长度不能超过60位';return false;}
        // 电商平台的海关注册登记编号；电商平台未在海关注册登记，由电商企业发送订单的，以中国电子口岸发布的电商平台标识编号为准。
        if (!isset($param['ebpCode']) || !$param['ebpCode']) {$this->errmsg = '缺少电商平台代码';return false;}
        // 电商平台的海关注册登记名称；电商平台未在海关注册登记，由电商企业发送订单的，以中国电子口岸发布的电商平台名称为准。
        if (!isset($param['ebpName']) || !$param['ebpName']) {$this->errmsg = '缺少电商平台名称';return false;}
        // 电商企业的海关注册登记编号。
        if (!isset($param['ebcCode']) || !$param['ebcCode']) {$this->errmsg = '缺少电商企业代码';return false;}
        // 电商企业的海关注册登记名称。
        if (!isset($param['ebcName']) || !$param['ebcName']) {$this->errmsg = '缺少电商企业名称';return false;}
        // 商品实际成交价，含非现金抵扣金额。
        if (!isset($param['goodsValue']) || !$param['goodsValue']) {$this->errmsg = '缺少商品价格';return false;}
        // 不包含在商品价格中的运杂费，无则填写"0"。
        if (!isset($param['freight']) || !$param['freight']) {$param['freight'] = 0;}
        // 使用积分、虚拟货币、代金券等非现金支付金额，无则填写"0"。
        if (!isset($param['discount']) || !$param['discount']) {$param['discount'] = 0;}
        // 企业预先代扣的税款金额，无则填写“0”
        if (!isset($param['taxTotal']) || !$param['taxTotal']) {$param['taxTotal'] = 0;}
        // 商品价格+运杂费+代扣税款-非现金抵扣金额，与支付凭证的支付金额一致。
        if (!isset($param['acturalPaid']) || !$param['acturalPaid']) {$this->errmsg = '缺少实际支付金额';return false;}
        if ($param['goodsValue']*100 + $param['freight']*100 + $param['taxTotal']*100 - $param['discount']*100 != $param['acturalPaid']*100) {$this->errmsg = '实际支付金额应 等于 商品价格+运杂费+代扣税款-非现金抵扣金额';return false;}
        // 限定为人民币，填写“142”。
        if (!isset($param['currency']) || !$param['currency']) {$param['currency'] = 142;}
        if ($param['currency'] != '142') {$this->errmsg = '币制应为人民币代码142';return false;}
        // 订购人的交易平台注册号。
        if (!isset($param['buyerRegNo']) || !$param['buyerRegNo']) {$this->errmsg = '缺少订购人注册号';return false;}
        // 订购人的真实姓名。
        if (!isset($param['buyerName']) || !$param['buyerName']) {$this->errmsg = '缺少订购人姓名';return false;}
        // 1-身份证,2-其它。限定为身份证，填写“1”。
        if (!isset($param['buyerIdType']) || !$param['buyerIdType']) {$param['buyerIdType'] = '1';}
        if (!in_array($param['buyerIdType'], array('1','2'))) {$this->errmsg = '订购人证件类型格式应为:1(身份证)或2(其他)';return false;}
        // 订购人的身份证件号码。
        if (!isset($param['buyerIdNumber']) || !$param['buyerIdNumber']) {$this->errmsg = '缺少订购人证件号码';return false;}
        // 海关监管对象的电话，要求实际联系电话
        if (!isset($param['buyerTelephone']) || !$param['buyerTelephone']) {$this->errmsg = '缺少订购人电话';return false;}
        // 支付企业的海关注册登记编号。
        if ((isset($param['payTransactionId']) && $param['payTransactionId']) 
            && (!isset($param['payCode']) || !$param['payCode'])) {$param['payCode'] = '312226T001';} // 非必填
        // 支付企业在海关注册登记的企业名称。
        if ((isset($param['payTransactionId']) && $param['payTransactionId']) 
            && (!isset($param['payName']) || !$param['payName'])) {$param['payName'] = '支付宝(中国)网络技术有限公司';} // 非必填
        // 支付企业唯一的支付流水号。
        // if (!isset($param['payTransactionId']) || !$param['payTransactionId']) {$this->errmsg = '缺少支付交易编号，未支付订单无法报关';return false;} // 非必填
        // 商品批次号。
        // if (!isset($param['batchNumbers']) || !$param['batchNumbers']) {$this->errmsg = '缺少商品批次号';return false;} // 非必填
        // 收货人姓名，必须与电子运单的收货人姓名一致。
        if (!isset($param['consignee']) || !$param['consignee']) {$this->errmsg = '缺少收货人姓名';return false;}
        // 收货人联系电话，必须与电子运单的收货人电话一致。
        if (!isset($param['consigneeTelephone']) || !$param['consigneeTelephone']) {$this->errmsg = '缺少收货人电话';return false;}
        // 收货地址，必须与电子运单的收货地址一致。
        if (!isset($param['consigneeAddress']) || !$param['consigneeAddress']) {$this->errmsg = '缺少收货地址';return false;}
        // 参照国家统计局公布的国家行政区划标准填制。
        // if (!isset($param['consigneeDistrict']) || !$param['consigneeDistrict']) {$this->$errmsg = '缺少收货地址行政区划代码(邮政编码)';return false;} // 非必填

        // if (!isset($param['note']) || !$param['note']) {$this->$errmsg = '缺少参数note';return false;} // 非必填

        return true;
    }


    /**
     * 验证参数
     */
    public function verifyGoodsInfo($param) {
        // 从1开始的递增序号。
        if (!isset($param['gnum']) || !$param['gnum']) {$this->errmsg = '缺少商品序号'; return false;}
        // 电商企业自定义的商品货号（SKU）。
        // if (!isset($param['itemNo']) || !$param['itemNo']) {$this->errmsg = '缺少企业商品货号'; return false;}              // 非必填
        // 交易平台销售商品的中文名称。
        if (!isset($param['itemName']) || !$param['itemName']) {$this->errmsg = '缺少企业商品名称'; return false;}
        // 满足海关归类、审价以及监管的要求为准。包括：品牌、规格、型号等。
        if (!isset($param['gmodel']) || !$param['gmodel']) {$param['gmodel'] = $param['itemName'];}
        // 交易平台销售商品的描述信息。
        // if (!isset($param['itemDescribe']) || !$param['itemDescribe']) {$this->errmsg = '缺少企业商品描述'; return false;}  // 非必填
        // 国际通用的商品条形码，一般由前缀部分、制造厂商代码、商品代码和校验码组成。
        // if (!isset($param['barCode']) || !$param['barCode']) {$this->errmsg = '缺少条形码'; return false;}            // 非必填
        // 填写海关标准的参数代码，参照《JGS-20 海关业务代码集》- 计量单位代码。
        if (!isset($param['unit']) || !$param['unit']) {$this->errmsg = '缺少单位'; return false;}
        // 商品实际数量。
        if (!isset($param['qty']) || !$param['qty']) {$this->errmsg = '缺少数量'; return false;}
        // 商品单价。赠品单价填写为“0”。
        if (!isset($param['price']) || !$param['price']) {$this->errmsg = '缺少单价'; return false;}
        // 商品总价，等于单价乘以数量。
        if (!isset($param['totalPrice']) || !$param['totalPrice']) {$this->errmsg = '缺少总价'; return false;}
        // 限定为人民币，填写“142”。
        if (!isset($param['currency']) || !$param['currency']) {$this->errmsg = '缺少币制'; return false;}
        // 填写海关标准的参数代码，参照《JGS-20 海关业务代码集》-国家（地区）代码表。
        if (!isset($param['country']) || !$param['country']) {$this->errmsg = '缺少原产国'; return false;}
        // 促销活动，商品单价偏离市场价格的，可以在此说明。
        // if (!isset($param['note']) || !$param['note']) {$this->errmsg = '缺少备注'; return false;}                  // 非必填

        return true;
    }
}


//——请根据您的业务逻辑来编写程序（以上代码仅作参考）——

?>